package com.gph.saviorframework.wf.service.impl;

import com.gph.saviorframework.Constants;
import com.gph.saviorframework.SaviorFrameworkException;
import com.gph.saviorframework.common.model.User;
import com.gph.saviorframework.security.service.UserService;
import com.gph.saviorframework.util.DateUtils;
import com.gph.saviorframework.wf.model.ActivitiDefConfig;
import com.gph.saviorframework.wf.model.ProcessResult;
import com.gph.saviorframework.wf.service.ActivitiDefService;
import com.gph.saviorframework.wf.service.ActivitiInsService;
import com.gph.saviorframework.wf.service.ActivitiProcessResultService;
import com.gph.saviorframework.wf.service.ActivitiTaskService;
import com.gph.saviorframework.wf.utils.WorkflowUtils;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.*;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.ProcessEngineImpl;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class ActivitiInsServiceImpl implements ActivitiInsService {

    @Autowired
    private ProcessEngine processEngine;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;
    
    @Autowired
    private TaskService taskService;

    @Autowired
    private IdentityService identityService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private ActivitiTaskService activitiTaskService;
    
    @Autowired
    private ActivitiDefService activitiDefService;

    @Autowired
    private UserService userService;

    @Autowired
    private ActivitiProcessResultService activitiProcessResultService;

    /**
     * 启动流程实例
     *
     * @param processDefinitionKey 流程定义key
     * @param businessKey          业务key
     * @param userId               启动人员编号
     * @return
     */
    public String startProcessInstance(String processDefinitionKey, String businessKey, String userId) {
        identityService.setAuthenticatedUserId(userId);
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(processDefinitionKey)
                .active().latestVersion().singleResult();

        ProcessInstance processInstance = null;
        if(definition!=null) {
            processInstance = runtimeService.startProcessInstanceById(definition.getId(), businessKey);
            //插入processResult
            ProcessResult processResult = new ProcessResult();
            processResult.setUserId(userId);
            processResult.setApplyType(processDefinitionKey);
            processResult.setApplyResult("DOING");
            processResult.setApplyId(businessKey);
            processResult.setProcessInsId(processInstance.getId());

            activitiProcessResultService.save(processResult);
        }
        identityService.setAuthenticatedUserId(null);
        return processInstance.getId();
    }

    /**
     * 启动流程实例，同时传入流程变量
     *
     * @param processDefinitionKey
     * @param businessKey
     * @param userId
     * @param variables
     * @return
     */
    public String startProcessInstanceWithVariables(String processDefinitionKey, String businessKey, String userId, Map<String, Object> variables) {
        identityService.setAuthenticatedUserId(userId);
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(processDefinitionKey)
                .active().latestVersion().singleResult();

        ProcessInstance processInstance = null;
        if(definition!=null) {
            processInstance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables);
            //插入processResult
            ProcessResult processResult = new ProcessResult();
            processResult.setUserId(userId);
            processResult.setApplyType(processDefinitionKey);
            processResult.setApplyResult("DOING");
            processResult.setApplyId(businessKey);
            processResult.setProcessInsId(processInstance.getId());

            activitiProcessResultService.save(processResult);
        }
        identityService.setAuthenticatedUserId(null);
        return processInstance.getId();
    }

    /**
     * 启动流程实例，同时传入配置参数，在实际实现中将配置参数转化为json字符串
     *
     * @param processDefinitionKey
     * @param businessKey
     * @param userId
     * @param configs
     * @return
     */
    public String startProcessInstanceWithConfigs(String processDefinitionKey, String businessKey, String userId, List<ActivitiDefConfig> configs) {
        if(configs==null||configs.size()<=0){
            return startProcessInstance(processDefinitionKey,businessKey,userId);
        }
        else{
            Map<String,Object> vars = new LinkedHashMap<String, Object>();

            for(ActivitiDefConfig config : configs){
                vars.put(config.getTaskId(),config);//到实际的listener中去解析
            }

            return startProcessInstanceWithVariables(processDefinitionKey, businessKey, userId, vars);
        }
    }

    /**
     * 获取活动的流程实例
     *
     * @param processDefinitionKey
     * @param userId
     * @param start
     * @param limit
     * @param sort
     * @param dir
     * @return
     */
    public List<HistoricProcessInstance> findActiveProcessInstance(String processDefinitionKey, String userId, Integer start, Integer limit, String sort, String dir) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                .startedBy(userId)
                .processDefinitionKey(processDefinitionKey)
                .unfinished()
                .orderByProcessInstanceStartTime();
        if(dir.toLowerCase().equals(Constants.DEFAULT_SORT_DIRECTION)) {
            historicProcessInstanceQuery = historicProcessInstanceQuery.asc();
        } else {
            historicProcessInstanceQuery = historicProcessInstanceQuery.desc();
        }
        if(start != null && limit != null) {
            return historicProcessInstanceQuery.listPage(start, limit);
        }
        return historicProcessInstanceQuery.list();
    }

    /**
     * 获取活动的流程实例数量
     *
     * @param processDefinitionKey
     * @param userId
     * @return
     */
    public long countActiveProcessInstance(String processDefinitionKey, String userId) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                .startedBy(userId)
                .processDefinitionKey(processDefinitionKey)
                .unfinished();
        return historicProcessInstanceQuery.count();
    }

    /**
     * 获取已经完成的流程实例
     *
     * @param processDefinitionKey
     * @param userId
     * @param start
     * @param limit
     * @param sort
     * @param dir
     * @return
     */
    public List<HistoricProcessInstance> findFinishedProcessInstance(String processDefinitionKey, String userId, Integer start, Integer limit, String sort, String dir) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                .startedBy(userId)
                .processDefinitionKey(processDefinitionKey)
                .finished()
                .orderByProcessInstanceEndTime();
        if(dir.toLowerCase().equals(Constants.DEFAULT_SORT_DIRECTION)) {
            historicProcessInstanceQuery = historicProcessInstanceQuery.asc();
        } else {
            historicProcessInstanceQuery = historicProcessInstanceQuery.desc();
        }
        if(start != null && limit != null) {
            return historicProcessInstanceQuery.listPage(start, limit);
        }
        return historicProcessInstanceQuery.list();
    }

    /**
     * 根据流程实例编号获取流程实例
     *
     * @param processInstanceId
     * @return
     */
    public HistoricProcessInstance findFinishedProcessInstance(String processInstanceId) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).finished();

        return historicProcessInstanceQuery.singleResult();
    }

    /**
     * 根据流程实例编号获取流程实例
     *
     * @param processInstanceId
     * @return
     */
    public HistoricProcessInstance findProcessInstance(String processInstanceId) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId);

        return historicProcessInstanceQuery.singleResult();
    }

    /**
     * 获取未完成的流程实例
     *
     * @param processInstanceId
     * @return
     */
    public HistoricProcessInstance findUnFinishedProcessInstance(String processInstanceId) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).unfinished();

        return historicProcessInstanceQuery.singleResult();
    }

    /**
     * 获取历史流程实例
     *
     * @param processInstanceId
     * @return
     */
    public HistoricProcessInstance findHistoryProcessInstance(String processInstanceId) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId);

        return historicProcessInstanceQuery.singleResult();
    }

    /**
     * 获取完成的流程实例数
     *
     * @param processDefinitionKey
     * @param userId
     * @return
     */
    public long countFinishedProcessInstance(String processDefinitionKey, String userId) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                .startedBy(userId)
                .processDefinitionKey(processDefinitionKey)
                .finished();
        return historicProcessInstanceQuery.count();
    }

    /**
     * 预览流程实例图，返回byte[]，客户端自行转化为InputStream，原因是kryo序列化方式不支持InputStream
     *
     * @param processInstanceId
     * @return
     */
    public byte[] viewProcessInstanceDiagram(String processInstanceId) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();

        if(processInstance==null){
            return "无运行中的流程".getBytes();
        }

        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService
                .getProcessDefinition(processInstance.getProcessDefinitionId());

        List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
        List<String> highLightedFlows = getHighLightedFlows(processInstanceId, processDefinition);

        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());

        ProcessEngineImpl defaultProcessEngine = (ProcessEngineImpl) ProcessEngines
                .getDefaultProcessEngine();

        Context.setProcessEngineConfiguration(defaultProcessEngine
                .getProcessEngineConfiguration());

        ProcessEngineConfiguration processEngineConfiguration = processEngine
                .getProcessEngineConfiguration();

        ProcessDiagramGenerator diagramGenerator = processEngineConfiguration
                .getProcessDiagramGenerator();

        InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel,
                "png", highLightedActivities, highLightedFlows,
                processEngineConfiguration.getActivityFontName(),
                processEngineConfiguration.getLabelFontName(),
                processEngineConfiguration.getClassLoader(), 1.0);

        try {
            return IOUtils.toByteArray(imageStream);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public byte[] viewProcessInstanceDiagram(String processInstanceId,String resourceType) {
        InputStream resourceAsStream = null;
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if(processInstance==null){
            return "无运行中的流程".getBytes();
        }
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId())
                .singleResult();

        String resourceName = "";
        if (resourceType.equals("image")) {
            resourceName = processDefinition.getDiagramResourceName();
        } else if (resourceType.equals("xml")) {
            resourceName = processDefinition.getResourceName();
        }
        resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
        try {
            return IOUtils.toByteArray(resourceAsStream);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private List<String> getHighLightedFlows(String processInstanceId, ProcessDefinitionEntity processDefinitionEntity) {
        List<String> highFlows = new ArrayList<String>();
        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();
        if(historicActivityInstances!=null){
            for (int i = 0; i < historicActivityInstances.size() - 1; i++) {
    			/*得到节点定义的详细信息*/
                ActivityImpl activityImpl = processDefinitionEntity.findActivity(historicActivityInstances.get(i).getActivityId());
    			/*用以保存后需开始时间相同的节点*/
                List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();
    			/*将后面第一个节点放在时间相同节点的集合里*/
                ActivityImpl sameActivityImpl1 = processDefinitionEntity.findActivity(historicActivityInstances.get(i + 1).getActivityId());
                sameStartTimeNodes.add(sameActivityImpl1);

                for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {
    				/*后续第一个节点*/
                    HistoricActivityInstance activityImpl1 = historicActivityInstances.get(j);
    				/*后续第二个节点*/
                    HistoricActivityInstance activityImpl2 = historicActivityInstances.get(j + 1);
    				/*如果第一个节点和第二个节点开始时间相同保存*/
                    if (activityImpl1.getStartTime().equals(activityImpl2.getStartTime())) {
                        ActivityImpl sameActivityImpl2 = processDefinitionEntity.findActivity(activityImpl2.getActivityId());
                        sameStartTimeNodes.add(sameActivityImpl2);
                    }
    				/*有不相同跳出循环*/
                    else {
                        break;
                    }
                }
    			/*取出节点的所有出去的线*/
                List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions();
    			/*对所有的线进行遍历*/
                for (PvmTransition pvmTransition : pvmTransitions) {
    				/*如果取出的线的目标节点存在时间相同的节点里，保存该线的id，进行高亮显示*/
                    ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition.getDestination();
                    if (sameStartTimeNodes.contains(pvmActivityImpl)) {
                        highFlows.add(pvmTransition.getId());
                    }
                }
            }
        }
        return highFlows;
    }

    /**
     * 流程跟踪
     *
     * @param processInstanceId
     * @return
     * @throws Exception
     */
    public List<Map<String, Object>> traceProcess(String processInstanceId) throws Exception {
        Execution execution = runtimeService.createExecutionQuery().executionId(processInstanceId).singleResult();//执行实例
        /*Object property = PropertyUtils.getProperty(execution, "activityId");
        String activityId = "";
        if (property != null) {
            activityId = property.toString();
        }*/
        Task task = activitiTaskService.getCurrentTaskInfo(processInstanceId);
        String activityId = "";
        if (task != null) {
            activityId = task.getTaskDefinitionKey();
        }
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
                .singleResult();
        if(processInstance==null){
            return null;
        }
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition(processInstance.getProcessDefinitionId());
        List<ActivityImpl> activitiList = processDefinition.getActivities();//获得当前任务的所有节点

        List<Map<String, Object>> activityInfos = new ArrayList<Map<String, Object>>();
        for (ActivityImpl activity : activitiList) {

            boolean currentActiviti = false;
            String id = activity.getId();

            // 当前节点
            if (id.equals(activityId)) {
                currentActiviti = true;
            }

            Map<String, Object> activityImageInfo = packageSingleActivitiInfo(activity, processInstance, currentActiviti,execution.getId());

            activityInfos.add(activityImageInfo);
        }

        return activityInfos;
    }

    /**
     * 封装输出信息，包括：当前节点的X、Y坐标、变量信息、任务类型、任务描述
     *
     * @param activity
     * @param processInstance
     * @param currentActiviti
     * @return
     */
    private Map<String, Object> packageSingleActivitiInfo(ActivityImpl activity, ProcessInstance processInstance,
                                                          boolean currentActiviti,String executionId) throws Exception {
        Map<String, Object> vars = new HashMap<String, Object>();
        Map<String, Object> activityInfo = new HashMap<String, Object>();
        activityInfo.put("currentActiviti", currentActiviti);
        setPosition(activity, activityInfo);
        setWidthAndHeight(activity, activityInfo);

        Map<String, Object> properties = activity.getProperties();
        vars.put("任务类型", WorkflowUtils.parseToZhType(properties.get("type").toString()));

        ActivityBehavior activityBehavior = activity.getActivityBehavior();
        if (activityBehavior instanceof UserTaskActivityBehavior) {

            Task currentTask = null;

			/*
             * 当前节点的task
			 */
            if (currentActiviti) {
                currentTask = activitiTaskService.getCurrentTaskInfo(processInstance);
            }

			/*
			 * 当前任务的分配角色
			 */
            UserTaskActivityBehavior userTaskActivityBehavior = (UserTaskActivityBehavior) activityBehavior;
            TaskDefinition taskDefinition = userTaskActivityBehavior.getTaskDefinition();
            Set<Expression> candidateGroupIdExpressions = taskDefinition.getCandidateGroupIdExpressions();
            if (!candidateGroupIdExpressions.isEmpty()) {

                // 任务的处理角色
                setTaskGroup(vars, candidateGroupIdExpressions);
            }
            //从流程变量中获取预设的执行人
            // 当前处理人
            if (currentTask != null) {
                setCurrentTaskAssignee(vars, currentTask);
            }
            else{
                String assignee = (String)runtimeService.getVariable(executionId, taskDefinition.getKey());
                if(!StringUtils.isEmpty(assignee)) {
                    vars.put("执行人", userService.get(assignee).getName());
                }
            }
        }

        vars.put("节点说明", properties.get("documentation"));

        String description = activity.getProcessDefinition().getDescription();
        vars.put("描述", description);

        activityInfo.put("vars", vars);
        return activityInfo;
    }

    private void setTaskGroup(Map<String, Object> vars, Set<Expression> candidateGroupIdExpressions) {
        String roles = "";
        for (Expression expression : candidateGroupIdExpressions) {
            String expressionText = expression.getExpressionText();
            String roleName = identityService.createGroupQuery().groupId(expressionText).singleResult().getName();
            roles += roleName;
        }
        vars.put("任务所属角色", roles);
    }

    /**
     * 设置坐标位置
     *
     * @param activity
     * @param activityInfo
     */
    private void setPosition(ActivityImpl activity, Map<String, Object> activityInfo) {
        activityInfo.put("x", activity.getX());
        activityInfo.put("y", activity.getY());
    }

    /**
     * 设置宽度、高度属性
     *
     * @param activity
     * @param activityInfo
     */
    private void setWidthAndHeight(ActivityImpl activity, Map<String, Object> activityInfo) {
        activityInfo.put("width", activity.getWidth());
        activityInfo.put("height", activity.getHeight());
    }

    /**
     * 设置当前处理人信息
     *
     * @param vars
     * @param currentTask
     */
    private void setCurrentTaskAssignee(Map<String, Object> vars, Task currentTask) {
        String assignee = currentTask.getAssignee();
        if (assignee != null) {
            User user = (User) userService.get(assignee);
            String userInfo = user.getName();
            vars.put("当前处理人", userInfo);
        }
    }

    /**
     * 获取所有完成的流程实例
     *
     * @param start
     * @param limit
     * @param sort
     * @param dir
     * @return
     */
    public List<HistoricProcessInstance> findAllFinishedProcessInstance(Integer start, Integer limit, String sort, String dir) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                .finished()
                .orderByProcessInstanceStartTime();
        if(dir.toLowerCase().equals(Constants.DEFAULT_SORT_DIRECTION)) {
            historicProcessInstanceQuery = historicProcessInstanceQuery.asc();
        } else {
            historicProcessInstanceQuery = historicProcessInstanceQuery.desc();
        }
        if(start != null && limit != null) {
            return historicProcessInstanceQuery.listPage(start, limit);
        }
        return historicProcessInstanceQuery.list();
    }

    /**
     * 计算所有完成的流程实例数量
     *
     * @return
     */
    public long countAllFinishedProcessInstance() {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                .finished();
        return historicProcessInstanceQuery.count();
    }

    /**
     * 获取正在运行的流程实例
     *
     * @param start
     * @param limit
     * @param sort
     * @param dir
     * @return
     */
    public List<HistoricProcessInstance> findRuntimeProcessInstance(Integer start, Integer limit, String sort, String dir) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                .unfinished()
                .orderByProcessInstanceStartTime();
        if(dir.toLowerCase().equals(Constants.DEFAULT_SORT_DIRECTION)) {
            historicProcessInstanceQuery = historicProcessInstanceQuery.asc();
        } else {
            historicProcessInstanceQuery = historicProcessInstanceQuery.desc();
        }
        if(start != null && limit != null) {
            return historicProcessInstanceQuery.listPage(start, limit);
        }
        return historicProcessInstanceQuery.list();
    }

    /**
     * 获取正在运行的流程实例
     *
     * @param defKey 流程定义key
     * @param start
     * @param limit
     * @param sort
     * @param dir
     * @return
     */
    @Override
    public List<HistoricProcessInstance> findRuntimeProcessInstance(String defKey, Integer start, Integer limit, String sort, String dir) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                .unfinished().processDefinitionKey(defKey)
                .orderByProcessInstanceStartTime();
        if(dir.toLowerCase().equals(Constants.DEFAULT_SORT_DIRECTION)) {
            historicProcessInstanceQuery = historicProcessInstanceQuery.asc();
        } else {
            historicProcessInstanceQuery = historicProcessInstanceQuery.desc();
        }
        if(start != null && limit != null) {
            return historicProcessInstanceQuery.listPage(start, limit);
        }
        return historicProcessInstanceQuery.list();
    }

    /**
     * 计算正在运行的流程实例数量
     *
     * @return
     */
    public long countRuntimeProcessInstance() {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
                .unfinished();
        return historicProcessInstanceQuery.count();
    }

    /**
     * 删除流程实例
     *
     * @param processInstanceId
     */
    public void deleteHistoryProcessInstance(String processInstanceId) {
        historyService.deleteHistoricProcessInstance(processInstanceId);
    }

    /**
     * 删除运行中的流程实例
     *
     * @param processInstanceId
     */
    public void deleteRuningProcessInstance(String processInstanceId) {
        deleteRuningProcessInstance(processInstanceId,"");
    }

    @Override
    public void deleteRuningProcessInstance(String processInstanceId, String deleteReason) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().
                processInstanceId(processInstanceId).singleResult();
        if(processInstance!=null){
            runtimeService.deleteProcessInstance(processInstanceId,deleteReason);
        }
    }

    /**
     * 获取所有的流程实例
     *
     * @param start
     * @param limit
     * @param sort
     * @param dir
     * @return
     */
    public Map<String, Object> findAllProcessInstanceMap(Integer start, Integer limit, String sort, String dir) {
        Map<String,Object> map = new HashMap<String, Object>();

        List<HistoricProcessInstance> list = findRuntimeProcessInstance(start, limit, sort, dir);

        List<Map<String, Object>> instanceList = new ArrayList<Map<String, Object>>();
        for(HistoricProcessInstance processInstance : list) {
            Map<String, Object> temp = new HashMap<String, Object>();
            temp.put("id", processInstance.getId());
            temp.put("key", processInstance.getBusinessKey());
            temp.put("name", processInstance.getName());
            temp.put("startUserId", processInstance.getStartUserId());
            temp.put("startTime", DateUtils.dateToString(processInstance.getStartTime(), "yyyy-MM-dd HH:mm:ss"));
            HistoricTaskInstance lastTask = activitiTaskService.getLastTask(processInstance.getId());
            temp.put("lastOperator", lastTask.getAssignee());
            temp.put("lastOperation", lastTask.getName());

            //temp.put("endTime",DateUtils.dateToString(processInstance.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
            instanceList.add(temp);
        }

        long records = countRuntimeProcessInstance();
        long total = 0;

        if(records%limit==0){
            total = records/limit;
        }
        else{
            total = records/limit + 1;
        }

        map.put(Constants.DEFAULT_RECORD_MODEL_KEY, instanceList);
        map.put(Constants.DEFAULT_COUNT_MODEL_KEY, total);//总页数
        map.put(Constants.DEFAULT_RECORDS_MODEL_KEY,records);//总记录数目
        map.put(Constants.DEFAULT_SUCCESS_KEY, Boolean.TRUE);

        return map;
    }

	@Override
	public void completeRuningProcessInstance(String processInstanceId) {
		try {
			HistoricProcessInstance historicProcessInstance = findUnFinishedProcessInstance(processInstanceId);
			if(historicProcessInstance!=null){
				List<ActivityImpl> endEvents = new ArrayList<ActivityImpl>();
				//获取到结束节点，然后触发结束事件
				List<ActivityImpl> activityImpls = activitiDefService.getAllActivities(historicProcessInstance.getProcessDefinitionId());
				for(ActivityImpl activityImpl : activityImpls){
					if("endEvent".equals(activityImpl.getProperty("type"))){
						endEvents.add(activityImpl);
					}
				}
				//触发结束事件
				if(endEvents.size()>0){
					activitiTaskService.jump2(processInstanceId, endEvents.get(0).getId());
					/*Task endTask = activitiTaskService.getCurrentTaskInfo(processInstanceId);
					taskService.complete(endTask.getId());*/
				}
			}
			else{
				throw new SaviorFrameworkException("no instance");
			}
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}
